package com.leyou.cart.service;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.leyou.cart.entity.Cart;
import com.leyou.common.auth.pojo.UserHolder;
import com.leyou.common.auth.pojo.UserInfo;
import com.leyou.common.constants.LyConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;


    /**
     * 添加购物车
     * 购物车数据结构为：<key, <hashKey, Cart>>
     * @param cart
     */
    public void addCart(Cart cart) {
        //得到当前用户id
        Long userId = UserHolder.getUserId();
        //得到购物车的key
        String cartkey = LyConstants.CART_PRE + userId;
        //得到当前用户的购物车数据
        BoundHashOperations<String, String, String> cartHashMap = redisTemplate.boundHashOps(cartkey);
        //获取当前新添加的购物车对象的hashKey
        String haskey = cart.getSkuId().toString();
        //判断当前新添加的购物车对象是否在原来的购物车集合中
        if (cartHashMap.hasKey(haskey)){
            //如果新添加的购物车对象已经存在于用户的购物车列表，则获取购物车列表中对应skuId的购物车对象
            String oldCartStr = cartHashMap.get(haskey);
            //将字符串格式的购物车对象转成对象格式
            Cart oldCart = JsonUtils.toBean(oldCartStr , Cart.class);
            //将原来购物车对象的数量合并到新添加的购物车对象中
            cart.setNum(oldCart.getNum() + cart.getNum());
        }
        //更新购物车
        cartHashMap.put(haskey , JsonUtils.toString(cart));
    }


    /**
     * 查询购物车列表
     */
    public List<Cart> findCarts() {

        Long userId = UserHolder.getUserId();

        String cartKey = LyConstants.CART_PRE + userId;

        if (!redisTemplate.hasKey(cartKey)) {
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }

        BoundHashOperations<String, String, String> cartHashMap = redisTemplate.boundHashOps(cartKey);

        List<String> carts = cartHashMap.values();

        if (CollectionUtils.isEmpty(carts)){
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }

        List<Cart> cartList = carts.stream()
                .map(cart->JsonUtils.toBean(cart,Cart.class))
                .collect(Collectors.toList());

        return cartList;
    }


    /**
     * 合并购物车,本质就是批量添加购物车
     */
    public void addCarts(List<Cart> carts) {
        for (Cart cart : carts) {
            addCart(cart);
        }
    }


    /**
     * 修改购物车商品的数量
     * @param id
     * @param num
     * @return
     */
    public void updateNum(Long id, Integer num) {
        // 获取当前用户
        Long userId = UserHolder.getUserId();

        String cartKey = LyConstants.CART_PRE + userId;

        // 获取hash操作的对象
        BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(cartKey);
        String hashKey = id.toString();
        Boolean boo = hashOps.hasKey(hashKey);
        if (boo == null || !boo) {
            log.error("购物车商品不存在，用户：{}, 商品：{}", userId, id);
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        // 查询购物车商品
        Cart c = JsonUtils.toBean(hashOps.get(hashKey), Cart.class);
        // 修改数量
        c.setNum(num);

        // 写回redis
        hashOps.put(hashKey, JsonUtils.toString(c));
    }


    /**
     * 删除购物车商品
     * @param skuId
     * @return
     */
    public void deleteCart(String skuId) {
        // 获取当前用户
        Long userId = UserHolder.getUserId();
        String cartKey = LyConstants.CART_PRE + userId;
        this.redisTemplate.opsForHash().delete(cartKey, skuId);
    }

    /**
     * 下单后购物车清除对于商品
     * @param mqMap
     */
    public void cartClear(HashMap<String, Object> mqMap) {
        String redisKey = mqMap.get("redisKey").toString();
        Object skuIdList = mqMap.get("skuIdList");
        List<String> skuIds = (List<String>) skuIdList;

        try {
            for (String skuId : skuIds) {
                redisTemplate.opsForHash().delete(redisKey, skuId);
            }
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.DELETE_OPERATION_FAIL);
        }
    }
}
